#ifndef _CTABLEBOX_H_
#define _CTABLEBOX_H_

#include <buola/gui/cwindow.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#include <boost/numeric/ublas/matrix.hpp>
#pragma GCC diagnostic pop

namespace buola { namespace gui {

using boost::numeric::ublas::matrix;

class CTableBox : public CWindow
{
    struct Position
    {
        bool mValid;
        TID mRow;
        TID mCol;
    };

public:
    CTableBox();
    ~CTableBox();
    
//Managing fields
    void Clear();

    void SetSize(int pRows,int pCols);
    void SetField(CPropertyField*);
    void SetRowTitle(int i,const std::wstring&);
    void SetColTitle(int i,const std::wstring&);
    void SetValues(const matrix<UAny>&);

    void SetValue(TID pRow,TID pCol,const UAny &pValue);
    const UAny &GetValue(TID pRow,TID pCol);
    void EditCell(TID pRow,TID pCol);
    
    void EnsureVisible(TID pRow,TID pCol,bool pMore);

    void SetIconStyle(int);

    void HighlightRow(int pRow,const img::CColor &pColor);
    void HighlightCol(int pCol,const img::CColor &pColor);
    void HighlightNone();

public:
////////////// Event handling //////////////
    virtual void OnExpose(const CExposeEvent &pE);
    void OnHScroll(int pPos);
    void OnVScroll(int pPos);
    virtual void OnButtonDown(const CMouseEvent &pE);
    virtual void OnButtonUp(const CMouseEvent &pE);
    virtual void OnMouseMove(const CMouseEvent &pE);
    virtual void OnKeyDown(const CKeyEvent &pE);
    virtual void OnSize(const CGeometryEvent &pE);

    virtual void OnStyleChanged(TStyle);

    virtual void OnFillMenu(PMenu,bool) {}

    void OnRulerChange(bool pFirst,bool pVertical,double pSize);

protected:
/////////////// protected functions //////////////
    void UpdateScrollBars();
    void FillRuler();

    void DrawAll(img::CGC*);
    void DrawAll(img::CGC*,const CRect_d &pRect);
    void DrawCell(img::CGC*,TID pRow,TID pCol,const CPoint_d &pPos,const CSize_d &pSize);

    Position GetCellAt(const CPoint_d&);

    void StartEditing(TID pRow,TID pCol);
    void EndEditing();
    void RestartEditing();

public:
    USignal<void(int pRow,int pCol)> sSelected;
    UEvent<void(int pRow,int pCol,UAny pValue)> eChanged;

private:
    PScrollBar mHScroll;
    PScrollBar mVScroll;

    PRulerBox mHRuler;
    PRulerBox mVRuler;

    Position mSelected;
    Position mEditing;
    CPropertyEditor *mEditor;

    int mIconStyle;

    CPropertyField *mField;
    matrix<UAny> mValues;

    double mXRange,mYRange;

/////////////////// static data ////////////////////
    static img::CPicture mImageExpand;
    static img::CPicture mImageCollapse;
};

/*namespace gui*/ } /*namespace buola*/ }

#endif
